package com.icee.myth.gm.client;

import com.google.protobuf.BlockingRpcChannel;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
import com.googlecode.protobuf.socketrpc.RpcChannels;
import com.googlecode.protobuf.socketrpc.RpcConnectionFactory;
import com.googlecode.protobuf.socketrpc.SocketRpcConnectionFactories;
import com.googlecode.protobuf.socketrpc.SocketRpcController;
import com.icee.myth.gm.config.ServerConfig;
import com.icee.myth.gm.player.SandBox;
import com.icee.myth.protobuf.ExternalCommonProtocol.*;
import com.icee.myth.protobuf.RpcServiceProtocol.*;
import com.icee.myth.utils.Consts;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import com.icee.myth.utils.StackTraceUtil;

import java.util.List;

/**
 * 通过RPC调用游戏服务器的函数。
 * @author yangyi
 */
public class GameServerClient {

    public ServerConfig serverConfig;

    public GameServerClient(ServerConfig serverConfig) {
        this.serverConfig = serverConfig;
    }

    public boolean addItem(int cid, int itemId, int itemNum) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();     //channel.newRpcController();
        // Create the request
        GMItemProto.Builder builder = GMItemProto.newBuilder();
        builder.setCid(cid);
        builder.setItemId(itemId);
        builder.setItemNum(itemNum);

        BoolValueProto result = null;
        try {
//            if (channel.isConnected()) {
            // Now try a blocking RPC request
            result = blockingService.addItem(controller, builder.build());
//            }
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
//            controller.reset();

            if (result != null) {
                System.out.printf("GM client addItem ok,cid=%d,itemId=%d,itemNum=%d\n",cid,itemId,itemNum);
                return result.getValue();
            }

        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "add item error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            controller.reset();
//            if (channel != null) {
//                channel.close();
//            }
        }

        return false;
    }

    public boolean removeItem(int cid, int itemId, int itemNum) {
//        NettyRpcClient client = new NettyRpcClient(
//                new NioClientSocketChannelFactory(
//                        Executors.newCachedThreadPool(),
//                        Executors.newCachedThreadPool()));

        BlockingRpcChannel channel = null;    //NettyRpcChannel channel = null;
        try {
            // Create channel
            RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                    .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
            channel = RpcChannels.newBlockingRpcChannel(connectionFactory);     //client.blockingConnect(new InetSocketAddress(serverConfig.host, serverConfig.rpcPort));

            ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

            // Get a new RpcController to use for this rpc call
            final RpcController controller = new SocketRpcController();     //channel.newRpcController();
            // Create the request
            GMItemProto.Builder builder = GMItemProto.newBuilder();
            builder.setCid(cid);
            builder.setItemId(itemId);
            builder.setItemNum(itemNum);

            BoolValueProto result = null;
//            if (channel.isConnected()) {
            // Now try a blocking RPC request
            result = blockingService.removeItem(controller, builder.build());
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
//            }
            controller.reset();

            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove item error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
//                channel.close();
            }
        }

        return false;
    }

    public boolean addCard(int cid, int cardTypeId, int cardLevel) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        GMCardProto.Builder builder = GMCardProto.newBuilder();
        builder.setCid(cid);
        builder.setCardTypeId(cardTypeId);
        builder.setCardLevel(cardLevel);

        // Now try a blocking RPC request
        try {
            // Call blocking service
            BoolValueProto result = blockingService.addCard(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "add card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean removeCard(int cid, int cardInstId) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        VariableValueProto.Builder builder = VariableValueProto.newBuilder();
        builder.setId(cid);
        builder.setValue(cardInstId);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.removeCard(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean changeSandbox(int cid, SandBox sandBox) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        GMSandboxProto.Builder builder = GMSandboxProto.newBuilder();
        builder.setCid(cid);
        builder.setSandbox(sandBox.buildSandboxProto());

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.changeSandbox(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean forbidLogin(int cid) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        IntValueProto.Builder builder = IntValueProto.newBuilder();
        builder.setValue(cid);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.kickPlayer(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean forbidTalk(int gameId, int endTime) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        VariableValueProto.Builder builder = VariableValueProto.newBuilder();
        builder.setId(gameId);
        builder.setValue(endTime);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.shutUp(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public int getId() {
        return serverConfig.id;
    }

    public String getName() {
        return serverConfig.name;
    }

    public int getPlayerCount() {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        VoidProto.Builder voidProtoBuilder = VoidProto.newBuilder();

        try {
            // Now try a blocking RPC request
            IntValueProto result = blockingService.getOnlinePlayerCount(controller, voidProtoBuilder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return -1;
    }

    public String getServerStatus() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public boolean broadcast(String message) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        StringValueProto.Builder builder = StringValueProto.newBuilder();
        builder.setValue(message);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.broadcast(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean rpcSet(int type, int cid, int num) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        VariableValueProto.Builder builder = VariableValueProto.newBuilder();
        builder.setId(cid);
        builder.setValue(num);

        BoolValueProto result = null;
        try {
            // Now try a blocking RPC request
            switch (type) {
                case Consts.RPCSET_SILVER: {
                    result = blockingService.setSilver(controller, builder.build());
                    break;
                }
                case Consts.RPCSET_GOLD1: {
                    result = blockingService.setGold1(controller, builder.build());
                    break;
                }
                case Consts.RPCSET_GOLD2: {
                    result = blockingService.setGold2(controller, builder.build());
                    break;
                }
                case Consts.RPCEDIT_GOLD1: {
                    result = blockingService.editGold1(controller, builder.build());
                    break;
                }
                case Consts.RPCEDIT_GOLD2: {
                    result = blockingService.editGold2(controller, builder.build());
                    break;
                }
                case Consts.RPCSET_ENERGY: {
                    result = blockingService.setEnergy(controller, builder.build());
                    break;
                }
                case Consts.RPCSET_VIPEXP: {
                    result = blockingService.setVipExp(controller, builder.build());
                    break;
                }
                case Consts.RPCSET_LEVEL: {
                    result = blockingService.setLevel(controller, builder.build());
                }
            }

            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }
        return false;
    }

    /** 注意： 该方法会在HttpServerHandler中调用，不是主线程（不是主线程访问该方法时必须确定主线程不会在此时关闭服务，因此需要与shutdown方法一起用synchronized）*/
    public synchronized List<Integer> getOnlinePlayerIds() {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        VoidProto.Builder voidProtoBuilder = VoidProto.newBuilder();

        try {
            // Now try a blocking RPC request
            IntValuesProto result = blockingService.getOnlinePlayerIds(controller, voidProtoBuilder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValuesList();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return null;
    }

    public boolean changePlayerName(int cid, String playerName) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        IntStringProto.Builder builder = IntStringProto.newBuilder();
        builder.setIntValue(cid);
        builder.setStringValue(playerName);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.changePlayerName(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public String consumerLog(int cid, int chargeType, long beginTime, long endTime) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        GMConsumerLogProto.Builder builder = GMConsumerLogProto.newBuilder();
        builder.setCid(cid);
        builder.setChargeType(chargeType);
        builder.setBeginTime(beginTime);
        builder.setEndTime(endTime);

        try {
            // Now try a blocking RPC request
            StringValueProto result = blockingService.consumerLog(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return "";
    }

    public boolean addMail(int targetId, MailContentProto mailContentProto) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        GMMailProto.Builder builder = GMMailProto.newBuilder();
        builder.setTargetId(targetId);
        builder.setContent(mailContentProto);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.addMail(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean addNormalActivity(String data) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        StringValueProto.Builder builder = StringValueProto.newBuilder();
        builder.setValue(data);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.addNormalActivity(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean deleteNormalActivity(int activityId) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        IntValueProto.Builder builder = IntValueProto.newBuilder();
        builder.setValue(activityId);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.deleteNormalActivity(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean setCardDrawActivity(String data) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        StringValueProto.Builder builder = StringValueProto.newBuilder();
        builder.setValue(data);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.setCardDrawActivity(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

    public boolean setStageActivity(String data) {
        // Create channel
        RpcConnectionFactory connectionFactory = SocketRpcConnectionFactories
                .createRpcConnectionFactory(serverConfig.host, serverConfig.rpcPort);
        BlockingRpcChannel channel = RpcChannels.newBlockingRpcChannel(connectionFactory);

        ManagerControlService.BlockingInterface blockingService = ManagerControlService.newBlockingStub(channel);

        // Get a new RpcController to use for this rpc call
        final RpcController controller = new SocketRpcController();
        // Create the request
        StringValueProto.Builder builder = StringValueProto.newBuilder();
        builder.setValue(data);

        try {
            // Now try a blocking RPC request
            BoolValueProto result = blockingService.setStageActivity(controller, builder.build());
            // Check success
            if (controller.failed()) {
                MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Rpc failed: %s" + controller.errorText());
            }
            if (result != null) {
                return result.getValue();
            }
        } catch (ServiceException ex) {
            MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "remove card error : " + StackTraceUtil.getStackTrace(ex));
        } finally {
            if (channel != null) {
                controller.reset();
            }
        }

        return false;
    }

}
